from app.db.session import SessionLocal
from app.models.generate import ModelList
from app.api.generate.schemas import model_list_schema as schema

from app.utils.curd_base import ModelCRUD
from app.utils import security
from app.utils.custom_response import success_response
from fastapi import APIRouter, Query, Body, Path, UploadFile, File, Form
from fastapi import Depends, Request
from sqlalchemy.orm import Session
from app.db.database import get_db
from app.models.system import Users
from typing import Any, Dict, Union, List, Optional
from fastapi.encoders import jsonable_encoder
from app.utils.custom_exc import CustomException
from sqlalchemy import func, or_, not_

from app.utils.file_storage import save_storage_file, delete_storage_file, get_storage_file


class ModelListCRUD(ModelCRUD):
    model = ModelList

    @staticmethod
    def serializer(queryset, only: tuple = (), date_format: str = None, datetime_format: str = None,
                   time_format: str = None):
        items = []
        for item in queryset:
            item_dict = item.to_dict(only=only)
            item_dict['image'] = get_storage_file(item_dict['image'])
            items.append(item_dict)
        return items


router = APIRouter()


@router.post("/create_model", summary="新增模型", response_model=schema.Res, name='新增模型')
async def create_model(
    *,
    db: Session = Depends(get_db),
    name: str = Form(description='名字'),
    path_name: str = Form(description='路径名字'),
    type: int = Form(1, description='类型'),
    detail: Optional[str] = Form(None, description='描述'),
    image: Optional[UploadFile] = File(None, description='图片'),
    current_user: Users = Depends(security.verify_admin_permission),
) -> Any:
    req_data = {'name': name, 'detail': detail, 'path_name': path_name, 'type': type}
    crud = ModelListCRUD()
    if image:
        path = save_storage_file(image, folder='generate/modelImage')
        req_data['image'] = path
    instance = crud.create(db, data=schema.Create.validate(req_data))
    only = ('id', 'name', 'detail', 'image', 'path_name', 'type')
    item_dict = instance.to_dict(only=only)
    item_dict['image'] = get_storage_file(item_dict['image'])
    return success_response(data=item_dict)


@router.post("/delete_model", summary="删除模型", response_model=schema.Res, name='删除模型')
async def delete_model(
    *,
    db: Session = Depends(get_db),
    req_data: schema.Del,
    current_user: Users = Depends(security.verify_admin_permission),
) -> Any:
    req_data = req_data.dict()
    crud = ModelListCRUD()
    queryset = crud.queryset(db)
    id_list = req_data.get('id', [])
    queryset = queryset.filter(crud.model.id.in_(id_list))
    for instance in queryset:
        delete_storage_file(instance.image)
    # crud.destroy(db, req_body=req_data)
    queryset.delete()
    db.commit()
    return success_response(data={})


@router.post("/update_model/{pk}", summary="更新模型", response_model=schema.Res, name='更新模型')
async def update_model(
    *,
    db: Session = Depends(get_db),
    pk,
    name: Optional[str] = Form(None, description='名字'),
    path_name: str = Form(None, description='路径名字'),
    type: int = Form(None, description='类型'),
    detail: Optional[str] = Form(None, description='描述'),
    image: Optional[UploadFile] = File(None, description='图片'),
    current_user: Users = Depends(security.verify_admin_permission),
) -> Any:
    req_data = {'name': name, 'detail': detail, 'path_name': path_name, 'type': type}
    crud = ModelListCRUD()
    instance = crud.get_object(db, pk)
    old_image = None
    if image:
        old_image = instance.image
        path = save_storage_file(image, folder='generate/modelImage')
        req_data['image'] = path
    instance = crud.update(db, instance=instance, data=schema.Update.validate(req_data))
    delete_storage_file(old_image)
    only = ('id', 'name', 'detail', 'image', 'path_name', 'type')
    item_dict = instance.to_dict(only=only)
    item_dict['image'] = get_storage_file(item_dict['image'])
    return success_response(data=item_dict)


able_filter_list = [
    {'name': 'name', 'source_filed': 'name', 'lookup_expr': 'ic', 'label': '包含名字', 'type': str, 'method': None, 'required': False},
    {'name': 'type', 'source_filed': 'type', 'lookup_expr': 'eq', 'label': '类型', 'type': int, 'method': None, 'required': False},
]


@router.get("/get_model_list", summary="获取模型列表", response_model=schema.Res, name='获取模型列表')
async def get_server_list(
    request: Request,
    *,
    db: Session = Depends(get_db),
    page: int = Query(1, description='页码', ge=1),
    page_size: int = Query(10, description='页面大小', le=50, ge=1),
    name: str = Query(None, description='名字'),
    current_user: Users = Depends(security.verify_access_token),
) -> Any:
    crud = ModelListCRUD()
    order_by_fields = ('-id',)
    queryset, total = crud.get_page_queryset(db, page=page, page_size=page_size, req_data=request.query_params, able_filter_list=able_filter_list, order_by_fields=order_by_fields)
    only = ('id', 'name', 'detail', 'image', 'path_name', 'type')
    items = crud.serializer(queryset, only=only)
    resp = {
        "items": items,
        'total': total
    }
    return success_response(data=resp)




